/*
 * Copyright (c) 2009 Roman Savelyev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#define __TESTABLE__ friend class CImportsWalkerTest;

#include "ImportsWalkerTest.h"
#include <f32image.h>
#include "ImportsWalker.h"
#include "Logger.h"

_LIT8(KDllName, "test.dll");
_LIT8(KDllNameWithSID, "test{1234AbCd}.dll");
_LIT8(KDllNameOpenCurly, "test{1234AbCd.dll");
_LIT8(KDllNameCloseCurly, "test1234AbCd}.dll");
_LIT8(KDllNameLongSID, "test{123456789ABCDEF}.dll");
_LIT8(KDllNameWrongSID, "test{1234ZBCd}.dll");
static const TUid KUid = {0x1234ABCD};

namespace CxxTest
	{
	template<> class ValueTraits<TUid>
		{
		TUint8 _asString[2 + 8 + 1];
	public:
		ValueTraits(TUid aUid)
			{
			TPtr8 ptr(_asString, 0, sizeof(_asString));
			ptr.Format(_L8("%08x"), aUid.iUid);
			ptr.Append(0);
			}
		const char* asString() const
			{
			return (const char*)_asString;
			}
		};

	template<> class ValueTraits<TUidType>
		{
		TUint8 _asString[2 + 3*8 + 1];
	public:
		ValueTraits(TUidType aUidType)
			{
			const char* uidOne = ValueTraits(aUidType[0]).asString();
			const char* uidTwo = ValueTraits(aUidType[1]).asString();
			const char* uidThree = ValueTraits(aUidType[2]).asString();
			TPtr8 ptr(_asString, 0, sizeof(_asString));
			ptr.AppendFormat(_L8("%s:%s:%s"), uidOne, uidTwo, uidThree);
			ptr.Append(0);
			}
		const char* asString() const
			{
			return (const char*)_asString;
			}
		};

	template<> class ValueTraits<TAny*>
		{
		TBuf8<2 + 8 + 1> iBuffer;
	public:
		ValueTraits(TAny* aPtr)
			{
			iBuffer.AppendFormat(_L8("0x%08x"), aPtr);
			iBuffer.Append(0);
			}
		const char* asString() const
			{
			return (const char*)iBuffer.Ptr();
			}
		};
	}

CImportsWalkerTest::CImportsWalkerTest(const TDesC8& aSuitName) : CxxTest::TestSuite(aSuitName)
    {}

void CImportsWalkerTest::testInitiatlValues()
	{
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.BranchOffset(), KErrNotFound);
	TS_ASSERT_EQUALS(walker.iCurrentImport, 0);
	TS_ASSERT_EQUALS(walker.iImportBlocks.Length(), 0);
	TS_ASSERT_EQUALS((TAny*)walker.iImportSection, NULL);
	TS_ASSERT_EQUALS(walker.LibraryName().Length(), 0);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), KErrNotReady);
	TS_ASSERT_EQUALS(walker.UidType(), TUidType(KNullUid, KNullUid, KNullUid));
	}

void CImportsWalkerTest::testEmptyImportSection()
	{
	E32ImportSection emptySection = {sizeof(E32ImportSection)};
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(emptySection, 0), KErrNone);
	TS_ASSERT_EQUALS(walker.iImportBlocks.Length(), 0);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 0);
	TS_ASSERT_EQUALS(walker.BranchOffset(), KErrNotFound);
	TS_ASSERT_EQUALS(walker.LibraryName(), KNullDesC8());
	}

void CImportsWalkerTest::testOneBlockImportSection()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImport;
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImport = 1;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.iImportBlocks.Length(), sizeof(section.iBlock) + sizeof(section.iImport));
	TS_ASSERT_EQUALS((TAny*)walker.iImportBlocks.Ptr(), (TAny*)&section.iBlock);
	}

void CImportsWalkerTest::testTwoBlocksImportSection()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlockOne;
		TUint iImportOne;
		E32ImportBlock iBlockTwo;
		TUint iImportTwo;
		TUint8 iBufferOne[sizeof(KDllName.iBuf)];
		TUint8 iBufferTwo[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlockOne.iNumberOfImports = 1;
			iBlockOne.iOffsetOfDllName = _FOFF(SImportSection, iBufferOne);
			iImportOne = 1;
			Mem::Copy(iBufferOne, KDllName.iBuf, sizeof(KDllName.iBuf));
			iBlockTwo.iNumberOfImports = 1;
			iBlockTwo.iOffsetOfDllName = _FOFF(SImportSection, iBufferTwo);
			iImportTwo = 1;
			Mem::Copy(iBufferTwo, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 2), KErrNone);
	TS_ASSERT_EQUALS(walker.iImportBlocks.Length(), _FOFF(SImportSection, iBufferOne) - _FOFF(SImportSection, iBlockOne));
	TS_ASSERT_EQUALS((TAny*)walker.iImportBlocks.Ptr(), (TAny*)&section.iBlockOne);
	}

void CImportsWalkerTest::testCorrectNumberOfImportsA()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[5];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 5;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			Mem::FillZ(iImports, sizeof(iImports));
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 5);
	}

void CImportsWalkerTest::testCorrectNumberOfImportsB()
    {
    struct SImportSection
        {
        E32ImportSection iSection;
        E32ImportBlock iBlockOne;
        TUint iImportsOne[6];
        E32ImportBlock iBlockTwo;
        TUint iImportsTwo[4];
        TUint8 iBufferOne[sizeof(KDllName.iBuf)];
        TUint8 iBufferTwo[sizeof(KDllName.iBuf)];
        SImportSection()
            {
            iSection.iSize = sizeof(SImportSection);
            iBlockOne.iNumberOfImports = 6;
            iBlockOne.iOffsetOfDllName = _FOFF(SImportSection, iBufferOne);
            Mem::FillZ(iImportsOne, sizeof(iImportsOne));
            Mem::Copy(iBufferOne, KDllName.iBuf, sizeof(KDllName.iBuf));
            iBlockTwo.iNumberOfImports = 4;
            iBlockTwo.iOffsetOfDllName = _FOFF(SImportSection, iBufferTwo);
            Mem::FillZ(iImportsTwo, sizeof(iImportsTwo));
            Mem::Copy(iBufferTwo, KDllName.iBuf, sizeof(KDllName.iBuf));
            }
        };
    SImportSection section;
    TImportsWalker walker;
    TS_ASSERT_EQUALS(walker.Set(section.iSection, 2), KErrNone);
    TS_ASSERT_EQUALS(walker.NumberOfImports(), 10);
    }

void CImportsWalkerTest::testZeroImportsNumberInBlock()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 0;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testNegativeImportsNumberInBlock()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = -1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testImportBlockNameOffsetInsideImportBlock()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBlock) + 4;
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testImportBlockNameOffsetPastImportSection()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer) + sizeof(iBuffer) + 4;
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testImportBlockNameOffsetInsideSectionHeader()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iSection);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testImportBlockNameWithoutTerminator()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf) - 1];
		SImportSection()
			{
			Mem::Fill(this, sizeof(SImportSection), 0xAA);
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllName.iBuf, KDllName().Length());
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testNextReturnsKErrNotReadyIfNoSet()
	{
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Next(), KErrNotReady);
	}

void CImportsWalkerTest::testNextReturnsKErrNotReadyIfSetFailed()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBlock);
			iImports[0] = 0;
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	TS_ASSERT_EQUALS(walker.Next(), KErrNotReady);
	}

void CImportsWalkerTest::testLibraryNameCorrect()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
	TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
	}

void CImportsWalkerTest::testSIDCorrect()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllNameWithSID.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllNameWithSID.iBuf, sizeof(KDllNameWithSID.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
	TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
	TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
	TS_ASSERT_EQUALS(walker.UidType()[2], KUid);
	}

void CImportsWalkerTest::testUnMatchedOpeningCurly()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllNameOpenCurly.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllNameOpenCurly.iBuf, sizeof(KDllNameOpenCurly.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testUnMatchedClosingCurly()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllNameCloseCurly.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllNameCloseCurly.iBuf, sizeof(KDllNameCloseCurly.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testIncorrectSIDLength()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllNameLongSID.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllNameLongSID.iBuf, sizeof(KDllNameLongSID.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testIncorrectSIDFormat()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllNameWrongSID.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 0;
			Mem::Copy(iBuffer, KDllNameWrongSID.iBuf, sizeof(KDllNameWrongSID.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrCorrupt);
	}

void CImportsWalkerTest::testProcessingA()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 8;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 1);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 8);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNotFound);
	}

void CImportsWalkerTest::testProcessingB()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[2];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 2;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 8;
			iImports[1] = 45;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 2);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 8);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 45);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNotFound);
	}

void CImportsWalkerTest::testSwitchNextBlock()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlockOne;
		TUint iImportsOne[2];
		E32ImportBlock iBlockTwo;
		TUint iImportsTwo[1];
		TUint8 iBufferOne[sizeof(KDllName.iBuf)];
		TUint8 iBufferTwo[sizeof(KDllNameWithSID.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlockOne.iNumberOfImports = 2;
			iBlockOne.iOffsetOfDllName = _FOFF(SImportSection, iBufferOne);
			iImportsOne[0] = 8;
			iImportsOne[1] = 45;
			Mem::Copy(iBufferOne, KDllName.iBuf, sizeof(KDllName.iBuf));
			iBlockTwo.iNumberOfImports = 1;
			iBlockTwo.iOffsetOfDllName = _FOFF(SImportSection, iBufferTwo);
			iImportsTwo[0] = 27;
			Mem::Copy(iBufferTwo, KDllNameWithSID.iBuf, sizeof(KDllNameWithSID.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 2), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 3);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 45);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 27);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNotFound);
	}

void CImportsWalkerTest::testRepeatedNextAfterFinished()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 8;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 1);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 8);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TInt i = 0;
	while (i++ < 10)
		{
		TS_ASSERT_EQUALS(walker.Next(), KErrNotFound);
		}
	}

void CImportsWalkerTest::testReset()
	{
	struct SImportSection
		{
		E32ImportSection iSection;
		E32ImportBlock iBlock;
		TUint iImports[1];
		TUint8 iBuffer[sizeof(KDllName.iBuf)];
		SImportSection()
			{
			iSection.iSize = sizeof(SImportSection);
			iBlock.iNumberOfImports = 1;
			iBlock.iOffsetOfDllName = _FOFF(SImportSection, iBuffer);
			iImports[0] = 8;
			Mem::Copy(iBuffer, KDllName.iBuf, sizeof(KDllName.iBuf));
			}
		};
	SImportSection section;
	TImportsWalker walker;
	TS_ASSERT_EQUALS(walker.Set(section.iSection, 1), KErrNone);
	TS_ASSERT_EQUALS(walker.NumberOfImports(), 1);
	TS_ASSERT_EQUALS(walker.Next(), KErrNone);
		TS_ASSERT_EQUALS(walker.LibraryName(), KDllName());
		TS_ASSERT_EQUALS(walker.BranchOffset(), 8);
		TS_ASSERT_EQUALS(walker.UidType()[0], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[1], KNullUid);
		TS_ASSERT_EQUALS(walker.UidType()[2], KNullUid);
	TS_ASSERT_EQUALS(walker.Next(), KErrNotFound);
	walker.Reset();
	TS_ASSERT_EQUALS(walker.Next(), KErrNotReady);
	}

